﻿using System.Collections;
using System;
using System.Threading.Tasks;

namespace TinyAsset
{
    public abstract class AsyncOperationBase<T> : IEnumerator where T : AsyncOperationBase<T>
    {
        public virtual float Progress { get; protected set; }

        public virtual bool IsDone { get; protected set; }

        public event Action<T> onCompleted;

        public void NotifyCompletion()
        {
            IsDone = true;
            Progress = 1.0f;

            if (onCompleted != null)
            {
                onCompleted(this as T);
                onCompleted = null;
            }

            if (taskCompletionSource != null)
                taskCompletionSource.TrySetResult(this as T);
        }

        TaskCompletionSource<T> taskCompletionSource;

        public Task<T> Task
        {
            get
            {
                if (taskCompletionSource == null)
                {
                    taskCompletionSource = new TaskCompletionSource<T>();
                    if (IsDone)
                        taskCompletionSource.TrySetResult(this as T);
                }
                return taskCompletionSource.Task;
            }
        }

        object IEnumerator.Current => null;

        bool IEnumerator.MoveNext() { return !IsDone; }

        void IEnumerator.Reset() { }
    }
}